package com.ruoyi.quartz.task;

import java.util.List;

import com.ruoyi.common.constant.LoanConstants;
import com.ruoyi.common.utils.uuid.IdUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.ruoyi.bizsys.domain.CreditAccount;
import com.ruoyi.bizsys.domain.LoanOffset;
import com.ruoyi.bizsys.service.ILoanOffsetService;
import com.ruoyi.business.service.IBLoanInfoService;
import com.ruoyi.bizsys.utils.BizConstants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.redis.RedisCache;
import lombok.extern.slf4j.Slf4j;

/**
 * 冲账重跑
 *
 * @author ruoyi
 */
@Slf4j
@Component("loanOffsetRerun")
public class LoanOffsetRerun {

    @Autowired
    IBLoanInfoService bLoanInfoService;

    @Autowired
    ILoanOffsetService loanOffsetService;

    @Autowired
    private RedisCache redisCache;

    public void runBatch() {
        log.info("loanOffsetRerun任务 Start>>>>>>>>>>");

        //查询所有冲账失败的借据
        List<CreditAccount> list = bLoanInfoService.getLoanOffsetFailAccount();
        for (CreditAccount a : list) {
            //锁住客户账户再操作
            String lockKey = LoanConstants.CUST_ACCOUNT_LOCK_KEY_PREFIX + a.getCustNo();

            int j = 0;//重试次数
            while (j < LoanConstants.CUST_ACCOUNT_LOCK_REGET_COUNT) {//重试次数内
                j++;
                log.info("rerun客户号{}第{}次获取账户锁", a.getCustNo(), j);
                String lockValue = IdUtils.simpleUUID();
                boolean lock = redisCache.lock(lockKey, lockValue);//获取锁

                if (lock) {
                    long start = System.currentTimeMillis();
                    this.loanOffsetRerun(a);
                    long end = System.currentTimeMillis();
                    log.info("锁占用时间，耗时：" + (end - start) + " ms");
                } else {
                    log.info("rerun客户号{}第{}次获取账户锁失败", a.getCustNo(), j);

                    try {
                        Thread.sleep(LoanConstants.CUST_ACCOUNT_LOCK_SLEEP_TIME);
                    } catch (InterruptedException e) {
                        log.error("rerun线程sleep异常", e);
                    }
                }
            }
        }

        log.info("loanOffsetRerun任务 End>>>>>>>>>>");
    }

    private void loanOffsetRerun(CreditAccount account) {
        //执行借据跑批
        LoanOffset query = new LoanOffset();
        query.setCustNo(account.getCustNo());
        query.setLoanOffsetStatus(BizConstants.LOAN_OFFSET_STATUS_FAIL);
        query.setState(UserConstants.BUSINESS_NORMAL);
        List<LoanOffset> offsetList = loanOffsetService.selectLoanOffsetList(query);
        for (LoanOffset o : offsetList) {
            try {
                bLoanInfoService.loanOffset(account, o);
            } catch (Exception e) {
                log.error("根据冲账记录ID {}，冲账异常", o.getId(), e);
                o.setLoanOffsetStatus(BizConstants.LOAN_OFFSET_STATUS_FAIL);
                o.setLoanOffsetDesc("异常");
            } finally {
                loanOffsetService.updateLoanOffset(o);
            }
        }
    }
}